﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using MediaAssistant.Controls.WaitScreen;
using MediaAssistant.Data;
using MediaAssistant.Helper;
using MediaAssistant.Management;
using MefBasic;
using MefBasic.Commans;
using MefBasic.Threading;
using MediaAssistant.DAL;

namespace MediaAssistant.Controls.MusicSearchControl
{
    [Export]
    public class MusicSearchControlPresenter:APresenter<MusicSearchControlView>
    {
        [ImportingConstructor]
        public MusicSearchControlPresenter(MusicSearchControlView view) : base(view)
        {
            SearchCommand = new DelegateCommand(ExecuteSearch);
            CanSearchMusic = RegistryHelper.CanSearchMusic;
            CanSearchAlbum = RegistryHelper.CanSearchAlbum;
            CanSearchArtist = RegistryHelper.CanSearchArtist;
            CanSearchComposer = RegistryHelper.CanSearchComposer;
            CanSearchGenre = RegistryHelper.CanSearchGenre;
        }

        [Import]
        private LibraryDataSource DataSource { get; set; }

        public DelegateCommand SearchCommand { get; set; }

        private List<Music> _searchResult;
        public List<Music> SearchResult
        {
            get { return _searchResult; }
            set
            {
                _searchResult = value;
                OnPropertyChanged("SearchResult");
            }
        }

        [Import]
        private BackgroundScannerManager BackgroundScannerManager { get; set; }
        private void ExecuteSearch(object obj)
        {
            var searchText = (string)obj;
            if(string.IsNullOrWhiteSpace(searchText))
                return;
            WaitScreen.Show();
            BackgroundScannerManager.Pause();
            new Job(j=>DoSearch(searchText)).StartBlocked();
            DataSource.SetMusicResults(SearchResult);
            DataSource.UpdateDuration();
            BackgroundScannerManager.Resume();
            WaitScreen.Hide();
        }
        
        [Import]
        private WaitScreenService WaitScreen { get; set; }

        private void DoSearch(string searchText)
        {
            Debug.WriteLine("Waiting for lock at Music DoSearch");
            lock (DatabaseManager.LockObject)
            {
                Debug.WriteLine("lock at Music DoSearch");
                SearchResult = new List<Music>();
                var musics = DatabaseManager.Instance.GetAllMusics();
                var total = musics.Count();
                var current = 0;
                WaitScreen.Show(total,current);
                foreach (var music in musics)
                {
                    if(++current%10==0)
                        WaitScreen.Show(total, current);
                    if (IsMatch(music, searchText))
                    {
                        SearchResult.Add(music);
                    }
                }
                Debug.WriteLine("unlock at Music DoSearch");
            }
        }

        private bool IsMatch(Music music, string searchText)
        {
            if (CanSearchMusic && IsMatch(music.Title, searchText))
                return true;
            if (CanSearchMusic && IsMatch(music.FileName, searchText))
                return true;
            if (CanSearchAlbum && IsMatch(music.Album, searchText))
                return true;
            if (CanSearchArtist && IsMatch(music.Artist, searchText))
                return true;
            if (CanSearchComposer && IsMatch(music.Composer, searchText))
                return true;
            if (CanSearchGenre && IsMatch(music.Genre, searchText))
                return true;
            return false;
        }

        private static bool IsMatch(string actualData, string searchText)
        {
            return actualData != null && Regex.IsMatch(actualData, searchText, RegexOptions.IgnoreCase);
        }


        private bool _canSearchMusic;
        public bool CanSearchMusic
        {
            get { return _canSearchMusic; }
            set
            {
                RegistryHelper.CanSearchMusic = _canSearchMusic = value;
                OnPropertyChanged("CanSearchMusic");
            }
        }

        private bool _canSearchAlbum;
        public bool CanSearchAlbum
        {
            get { return _canSearchAlbum; }
            set
            {
                RegistryHelper.CanSearchAlbum = _canSearchAlbum = value;
                OnPropertyChanged("CanSearchAlbum");
            }
        }

        private bool _canSearchArtist;
        public bool CanSearchArtist
        {
            get { return _canSearchArtist; }
            set
            {
                RegistryHelper.CanSearchArtist = _canSearchArtist = value;
                OnPropertyChanged("CanSearchArtist");
            }
        }

        private bool _canSearchGenre;
        public bool CanSearchGenre
        {
            get { return _canSearchGenre; }
            set
            {
                RegistryHelper.CanSearchGenre = _canSearchGenre = value;
                OnPropertyChanged("CanSearchGenre");
            }
        }

        private bool _canSearchComposer;
        public bool CanSearchComposer
        {
            get { return _canSearchComposer; }
            set
            {
                RegistryHelper.CanSearchComposer = _canSearchComposer = value;
                OnPropertyChanged("CanSearchComposer");
            }
        }
    }
}
